﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WCFServicesForCitrix.Interfaces;

namespace WCFServicesForCitrix.XServer
{
    [System.ServiceModel.ServiceBehavior(AddressFilterMode=System.ServiceModel.AddressFilterMode.Any)]
    public class XenServer : Interfaces.IXenServer
    {
        public string GetData(string name)
        {

            return string.Format("Hello {0}!", name);

        }



        public string PutData(string name, ContactDetails details)
        {

            return string.Format("Hello {0} ({1})!", "test", details.SiteUrl);

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        internal XenAPI.Session GetSession(string host, int port, string username, string password)
        {
            try
            {
                XenAPI.Session _session = new XenAPI.Session(host, port);
                _session.login_with_password(username, password);

                return _session;
            }
            catch (System.Exception loginError)
            {
                return null;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Session"></param>
        /// <returns></returns>
        internal bool SessionLogout(XenAPI.Session Session)
        {
            Session.logout();
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="AuthUsername"></param>
        /// <param name="AuthPassword"></param>
        /// <returns></returns>
        public XServer.XSAuthTicket GetAuthTicket(string AuthUsername, string AuthPassword,bool UseServerSideAuthentication)
        {
            //Check for a valid user
            XServer.XSAuthTicket AuthTicket = new XSAuthTicket();
            AuthTicket.IsAuthenticated = true;// Convert.ToInt32(true);
            AuthTicket.UserServerAuth = UseServerSideAuthentication;
            AuthTicket.ErrorInformation = "";
            AuthTicket.Expiration = System.DateTime.Now.AddMinutes(30);
            //perform authentication.
            return AuthTicket;
        }

        public string PostTest(string host)
        {
            return "John";
        }
       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="Validate"></param>
        /// <param name="AuthTicket"></param>
        /// <returns></returns>
        public XServer.XSTicket GetServerTicket(string host, string port, string username, string password, string Validate, XServer.XSAuthTicket AuthTicket)
        {
            XServer.XSTicket _validTicket = new WCFServicesForCitrix.XServer.XSTicket();
            try
            {
                string pServerUsername = null;
                string pServerPassword = null;
                string pServerIP = null;

                if (Convert.ToBoolean(AuthTicket.UserServerAuth))
                {

                    ConfigurationHandlers.XenConfigurationSection ServerList = (ConfigurationHandlers.XenConfigurationSection)System.Configuration.ConfigurationManager.GetSection("XenConfig");
                    ConfigurationHandlers.XenServerElement RequestServerElement = ServerList.XenServers[host];
                    if (RequestServerElement != null)
                    {
                        pServerUsername = RequestServerElement.ServerUsername;
                        pServerPassword = RequestServerElement.ServerPassword;
                        pServerIP = RequestServerElement.IPAddress;
                    }
                    else
                    {
                        throw new Exception("Element is missing username/password attributes");
                    }
                    //foreach (ConfigurationHandlers.XenServerElement XenServer in ServerList.XenServers)
                    //{
                    //    if (XenServer.NetBiosName.ToLower() == host.ToLower() || XenServer.IPAddress.ToLower() == host.ToLower())
                    //    {
                    //        pServerUsername = XenServer.ServerUsername;
                    //        pServerPassword = XenServer.ServerPassword;
                    //    }
                    //}
                }
                else
                {
                    pServerUsername = username;
                    pServerPassword = password;
                }

                XenAPI.Session _session = this.GetSession(pServerIP, Convert.ToInt32(port), pServerUsername, pServerPassword);
                if (_session != null)
                {
                    _validTicket = new WCFServicesForCitrix.XServer.XSTicket();
                    _validTicket.Server = host;
                    _validTicket.Port = Convert.ToInt32(port);
                    if (Convert.ToBoolean(AuthTicket.UserServerAuth))
                    {
                        _validTicket.Username = null;
                        _validTicket.Password = null;
                    }
                    else
                    {
                        _validTicket.Username = username;
                        _validTicket.Password = password;
                    }
                    this.SessionLogout(_session);

                }

            }
            catch (System.Exception loginError)
            {
                _validTicket.isError = "TRUE";
                _validTicket.ErrorInformation = loginError.Message;
            }
            return _validTicket;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="AuthTicket"></param>
        /// <returns></returns>
        public List<XServer.XSServer> GetServers(XServer.XSAuthTicket AuthTicket)
        {
            List<XServer.XSServer> tempServerList = new List<XSServer>();

            ConfigurationHandlers.XenConfigurationSection ServerList = (ConfigurationHandlers.XenConfigurationSection)System.Configuration.ConfigurationManager.GetSection("XenConfig");

            foreach (ConfigurationHandlers.XenServerElement XenServer in ServerList.XenServers)
            {
                XServer.XSServer Server = new XSServer(XenServer.NetBiosName, XenServer.IPAddress, XenServer.Description);
                tempServerList.Add(Server);
            }
            return tempServerList;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ServerTicket"></param>
        /// <returns></returns>
        public List<XServer.XSVirtualMachine> GetServerTemplates(XServer.XSTicket ServerTicket)
        {
            List<XServer.XSVirtualMachine> tempServerTemplates = new List<XSVirtualMachine>();

            if (ServerTicket != null)
            {
                XenAPI.Session _session = this.GetSession(ServerTicket.Server, ServerTicket.Port, ServerTicket.Username, ServerTicket.Password);
                if (_session != null)
                {
                    List<XenAPI.XenRef<XenAPI.VM>> vmRefs = XenAPI.VM.get_all(_session);
                    foreach (XenAPI.XenRef<XenAPI.VM> VMRef in vmRefs)
                    {
                        XenAPI.VM VirtualMachine = XenAPI.VM.get_record(_session, VMRef);
                        if (VirtualMachine != null)
                        {
                            if (VirtualMachine.is_a_template == true)
                            {
                                XServer.XSVirtualMachine VM = new XSVirtualMachine();
                                VM.Name = VirtualMachine.name_label;
                                VM.Description = null;
                                VM.UUID = null;
                                tempServerTemplates.Add(VM);
                            }

                        }
                    }
                    this.SessionLogout(_session);
                }
            }

            return tempServerTemplates;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ServerTicket"></param>
        /// <returns></returns>
        public List<XServer.XSVirtualMachine> GetVirtualMachines(XServer.XSTicket ServerTicket)
        {
            List<XServer.XSVirtualMachine> tempVirtualMachines = new List<XSVirtualMachine>();

            if (ServerTicket != null)
            {
                XenAPI.Session _session = this.GetSession(ServerTicket.Server,ServerTicket.Port,ServerTicket.Username,ServerTicket.Password);
                if (_session != null)
                {
                    List<XenAPI.XenRef<XenAPI.VM>> vmRefs = XenAPI.VM.get_all(_session);
                    foreach ( XenAPI.XenRef<XenAPI.VM> VMRef in vmRefs )
                    {
                        XenAPI.VM VirtualMachine = XenAPI.VM.get_record(_session, VMRef);
                        if (VirtualMachine != null)
                        {
                            if (VirtualMachine.is_a_template == false)
                            {
                                XServer.XSVirtualMachine VM = new XSVirtualMachine();
                                VM.Name = VirtualMachine.name_label;
                                VM.Description = VirtualMachine.name_description;
                                VM.UUID = VirtualMachine.uuid;
                                tempVirtualMachines.Add(VM);
                            }

                        }
                    }
                    this.SessionLogout(_session);
                }
            }

            return tempVirtualMachines;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ServerTicket"></param>
        /// <param name="XenVirtuaMachine"></param>
        /// <returns></returns>
        public XServer.XSVirtualMachineProperties GetVirtualMachineProperties(XServer.XSTicket ServerTicket, XServer.XSVirtualMachine XenVirtuaMachine)
        {
            XServer.XSVirtualMachineProperties VMProps = new XSVirtualMachineProperties();
            XenAPI.Session _session = this.GetSession(ServerTicket.Server,ServerTicket.Port,ServerTicket.Username,ServerTicket.Password);
            if (_session != null)
            {
                XenAPI.XenRef<XenAPI.VM> vmRef = XenAPI.VM.get_by_uuid(_session, XenVirtuaMachine.UUID);

                XenAPI.VM VirtualMachine = XenAPI.VM.get_record(_session, vmRef);
                if (VirtualMachine != null)
                {
                    VMProps.Name = VirtualMachine.name_label;
                    VMProps.Description = VirtualMachine.name_description;
                    VMProps.NumberOfCPUs = VirtualMachine.VCPUs_max.ToString();
                    VMProps.ConfiguredMemory = VirtualMachine.memory_static_max.ToString();
                    //VMProps.LastBootFlags = VirtualMachine.last_boot_CPU_flags
                    XenAPI.XenRef<XenAPI.VM_guest_metrics> GuestMetics = VirtualMachine.guest_metrics;
                    if (GuestMetics.ServerOpaqueRef != null)
                    {
                        XenAPI.VM_guest_metrics GuestMetricsRef = XenAPI.VM_guest_metrics.get_record(_session, GuestMetics);
                        VMProps.DiskInfo = this.GetDiskInformation(GuestMetricsRef);
                        VMProps.NetworkInfo = this.GetNetworkInformation(GuestMetricsRef);
                    }
                    else
                    {
                        VMProps.DiskInfo = null;
                        VMProps.NetworkInfo = null;
                    }
                }
                this.SessionLogout(_session);
            }

            return VMProps;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="GuestMetricsRef"></param>
        /// <returns></returns>
        internal List<XServer.XSVirtualMachineDisk> GetDiskInformation(XenAPI.VM_guest_metrics GuestMetricsRef)
        {
            List<XServer.XSVirtualMachineDisk> tempDisk = new List<XSVirtualMachineDisk>();
            foreach (string DiskKey in GuestMetricsRef.disks.Keys)
            {
                XServer.XSVirtualMachineDisk Disk = new XSVirtualMachineDisk();
                Disk.Name = DiskKey;
                Disk.Value = GuestMetricsRef.disks[DiskKey].ToString();
                tempDisk.Add(Disk);
            }

            return tempDisk;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="GuestMetricsRef"></param>
        /// <returns></returns>
        internal List<XServer.XSVirtualMachineNetwork> GetNetworkInformation(XenAPI.VM_guest_metrics GuestMetricsRef)
        {
            List<XServer.XSVirtualMachineNetwork> tempNetwork = new List<XSVirtualMachineNetwork>();
            foreach (string NetworkKey in GuestMetricsRef.networks.Keys)
            {
                XServer.XSVirtualMachineNetwork Network = new XSVirtualMachineNetwork();
                Network.Name = NetworkKey;
                Network.Value = GuestMetricsRef.networks[NetworkKey];
                tempNetwork.Add(Network);
            }

            return tempNetwork;
        }
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="VirtualMachine"></param>
        ///// <param name="Action"></param>
        ///// <returns></returns>
        //public bool PerformVirtualMachineAction(XServer.XSVirtualMachine VirtualMachine, XServer.VMActions Action)
        //{
        //    return true;
        //}
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="VirtualMachine"></param>
        ///// <returns></returns>
        //public XServer.VMCurrentStatus GetVirtualMachineStatus(XServer.XSVirtualMachine VirtualMachine)
        //{
        //    return XServer.VMCurrentStatus.Started;
            
        //}
    }
}
